﻿using IndustrialCommunication.Core.Interface;
using IndustrialCommunication.Core;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace IndustrialCommunication.Core.Channel
{
    public class TcpChannel<TPackageInfo> : ChannelBase<TPackageInfo>
    {
        private Socket _socket;
        private IDataAdapter<TPackageInfo> _adapter;
        public TcpChannel(Socket socket,IDataAdapter<TPackageInfo> dataAdapter)
        {
            if (socket==null||dataAdapter==null)
            {
                throw new ArgumentNullException("socket or dataAdapter can't be null");
            }
            _socket = socket;
            _adapter = dataAdapter;
        }
        public override void Close()
        {
            try
            {
                _socket.Shutdown(SocketShutdown.Both);
            }
            finally
            {
                _socket.Close();
            }
        }
        public override  Task CloseAsync()
        {
            return Task.Run(() =>Close());
        }

        public override void Send(byte[] data)
        {
            _socket.Send(data);
        }

        public override  Task SendAsync(TPackageInfo package, IPackageEncoder<TPackageInfo> encoder)
        {
            return Task.Run(async () =>
            {
                var data=encoder.Encode(package);
                await _socket.SendAsync(data,SocketFlags.None);
            });
        }
        public TPackageInfo Receive()
        {
            var data = new byte[1024 * 5];
             _socket.Receive(data);
            return _adapter.Decoder.Decode(data);
        }
        public override async Task SendSync(byte[] data)
        {
            await _socket.SendAsync(data,SocketFlags.None).ConfigureAwait(false);
        }
    }
}
